package felix.rule.service.impl.install;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;

@Service
@Profile("install")
@Slf4j
public class SqlDatabaseInstallService {

    @Value("${spring.datasource.url}")
    protected String dbUrl;

    @Value("${spring.datasource.username}")
    protected String dbUserName;

    @Value("${spring.datasource.password}")
    protected String dbPassword;

    @Value("${install.data_dir:}")
    private String dataDir;

    public static final String APP_DIR = "dao";
    public static final String SRC_DIR = "src";
    public static final String MAIN_DIR = "main";
    public static final String RESOURCES_DIR = "resources";

    private static final String SQL_DIR = "sql";

    private String getDataDir() {
        if (!StringUtils.isEmpty(dataDir)) {
            if (!Paths.get(this.dataDir).toFile().isDirectory()) {
                throw new RuntimeException("'install.data_dir' property value is not a valid directory!");
            }
            return dataDir;
        } else {
            String workDir = System.getProperty("user.dir");
            if (workDir.endsWith(APP_DIR)) {
                return Paths.get(workDir, SRC_DIR, MAIN_DIR, SQL_DIR).toString();
            } else {
                Path dataDirPath = Paths.get(workDir, APP_DIR, SRC_DIR, MAIN_DIR, RESOURCES_DIR);
                if (Files.exists(dataDirPath)) {
                    return dataDirPath.toString();
                } else {
                    throw new RuntimeException("Not valid working directory: " + workDir + ". Please use either root project directory, application module directory or specify valid \"install.data_dir\" ENV variable to avoid automatic data directory lookup!");
                }
            }
        }
    }

    private void loadFunctions(Path sqlFile, Connection conn) throws Exception {
        String sql = new String(Files.readAllBytes(sqlFile), StandardCharsets.UTF_8);
        conn.createStatement().execute(sql);
    }


    public void loadSql(String fileName) throws Exception {
        Path schemaUpdateFile = Paths.get(getDataDir(), SQL_DIR, fileName);
        try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
            loadFunctions(schemaUpdateFile, conn);
        }
    }

}
